#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

class Base{
public:
    Base(const char * pstr)
    :_pbase(new char[strlen(pstr)+1]())
    {
        strcpy(_pbase,pstr);
    }

    Base(const Base & rhs)
    :_pbase(new char[strlen(rhs._pbase)+1]())
    {
        strcpy(_pbase,rhs._pbase);
    }

    Base & operator=(const Base & rhs){
        if(this != &rhs){
            delete [] _pbase;
            _pbase = new char[strlen(rhs._pbase)+1]();
            strcpy(_pbase,rhs._pbase);
        }
        return *this;
    }

    ~Base(){
        if(_pbase){
            delete [] _pbase;
            _pbase = nullptr;
        }
    }
protected:
    char * _pbase;
};

class Derived : public Base{
public:
    Derived(const char * pbase,const char * pderived)
    :Base(pbase)
    ,_pderived(new char[strlen(pderived)+1]())
    {
        strcpy(_pderived,pderived);
    }

    Derived(const Derived & rhs)
    :Base(rhs)
    ,_pderived(new char[strlen(rhs._pderived)+1]())
    {
        strcpy(_pderived,rhs._pderived);
    }

    Derived & operator=(const Derived & rhs){
        if(this != & rhs){
            Base::operator=(rhs);
            delete [] _pderived;
            _pderived = new char[strlen(rhs._pderived)+1]();
            strcpy(_pderived,rhs._pderived);
        }
        return *this;
    }

    ~Derived(){
        if(_pderived){
            delete [] _pderived;
            _pderived = nullptr;
        }
    }

    friend ostream & operator<<(ostream & os,const Derived & rhs);
private:
    char * _pderived;
};

ostream & operator<<(ostream & os,const Derived & rhs){
    if(rhs._pbase){
        os << rhs._pbase << " ";
    }
    if(rhs._pderived){
        os << rhs._pderived;
    }
    return os;
}

void test(){
    Derived d("hello","world");
    cout << d << endl;
}

int main()
{
    test();
    return 0;
}

